package mapViewer;

import context.*;

import java.util.Vector;
import java.util.Hashtable;
import java.util.Enumeration;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

import javax.microedition.rms.RecordStore;
import javax.microedition.rms.RecordStoreException;

public class AccountRecordStore implements Debug.Constants
{ //private static final boolean DEBUG=true; // Overriding Debug.Constants.DEBUG
  private static final String RECORDSTORE_NAME="MapViewerAccount";
  
  private static String selectedAccount;
  private static Vector accounts=new Vector();
  public static Vector getAccounts() { return(accounts); }
  
  public AccountRecordStore()
  { try { loadAll(); }
    catch(Exception e)
    { Debug.EXCEPTION("new AccountRecordStore: ",e);
      init();
    }
  }

  private void init()
  { AccountRecord account1=new AccountRecord("api.fleximap.com",80,"FlexiMap");
//    AccountRecord account2=new AccountRecord("jabber.com",5222,"jabber.com");
//    AccountRecord account3=new AccountRecord("jabber.org",5222,"jabber.org");
	accounts.addElement(account1);  
//	accounts.addElement(account2);  
//	accounts.addElement(account3);
	selectedAccount=account1.getAccountName();
  }
  
  public static void setSelectedAccount(String account)
  throws IOException,RecordStoreException
  {	selectedAccount=account;  
	storeAll();
  }
  
  public static AccountRecord getSelectedAccount() { return(getAccount(selectedAccount)); }
  
  public static AccountRecord newAccount()
  { AccountRecord account=new AccountRecord("talk.google.com",5222,"gmail.com");
	accounts.addElement(account);
	return(account);
  }
  public static void removeAccount(String accountName)
  { AccountRecord rec=getAccount(accountName);
	accounts.removeElement(rec);  
  }
  
  public static AccountRecord getAccount(String accountName)
  { for(int i=0;i<accounts.size();i++)
	{ AccountRecord rec=(AccountRecord)accounts.elementAt(i);
	  if(DEBUG) Debug.println("AccountRecordStore.getAccount: TEST  "+accountName+" vvs "+rec.getAccountName());
	  if(accountName.equals(rec.getAccountName())) return(rec);
	}
    return(null);
  }
  
  private static void writeFirstRecord(RecordStore rs) throws IOException,RecordStoreException
  { ByteArrayOutputStream bout=new ByteArrayOutputStream();
    DataOutputStream dout=new DataOutputStream( bout );
    if(DEBUG) Debug.println("writeFirstRecord: WRITE[1]: accounts="+accounts);
    dout.writeInt(accounts.size());
    dout.writeUTF(selectedAccount);
    
    Hashtable mapSheetSet=MapSheet.getMapSheetSet();
    dout.writeInt(mapSheetSet.size());
    dout.writeUTF(MapSheet.getSelectedMapSheet());
    
    byte[] record=bout.toByteArray();
    int n=rs.addRecord(record,0,record.length);
    if(DEBUG) Debug.println("AccountRecordStore.writeFirstRecord: n="+n+": "+new String(record));
    dout.close();
    bout.close();
  }
  
  // Utility variables:
  private int nAccounts;
  private int nMapSheets;
  private String selectedMapSheet;
//  private String selectedMapSheet;
  private int readFirstRecord(RecordStore rs) throws IOException,RecordStoreException
  { int n=rs.getRecordSize(1);
    byte[] rsData=new byte[n];
    ByteArrayInputStream bin = new ByteArrayInputStream(rsData);
    DataInputStream din = new DataInputStream(bin);
    rs.getRecord(1,rsData,0);
    if(DEBUG) Debug.println("AccountRecordStore.readFirstRecord: got: "+new String(rsData));
    nAccounts=din.readInt();
    selectedAccount=din.readUTF();
    nMapSheets=din.readInt();
    selectedMapSheet=din.readUTF();
//    MapSheet.setSelectedMapSheet(selectedMapSheet);
    bin.close();
    din.close();
    if(DEBUG) Debug.println("READ[1]: "+this);
    return(nAccounts);
  }

  public static void storeAll() throws IOException,RecordStoreException
  { RecordStore rs = null;
    try { RecordStore.deleteRecordStore(RECORDSTORE_NAME); }
    catch( Exception e ){ Debug.EXCEPTION("AccountRecordStore.storeAll",e); }
    try
    { rs=RecordStore.openRecordStore(RECORDSTORE_NAME,true);
      writeFirstRecord(rs);
      for(int i=0;i<accounts.size();i++)
      { AccountRecord rec=(AccountRecord)accounts.elementAt(i);
        rec.writeRecord(rs,i+2);
      }
      storeMapSheetSet(rs,accounts.size()+2);
    } finally {	rs.closeRecordStore(); }
  }
  
  private static void storeMapSheetSet(RecordStore rs,int recordId)
  throws IOException,RecordStoreException
  { Hashtable mapSheetSet=MapSheet.getMapSheetSet();
	for(Enumeration e=mapSheetSet.elements();e.hasMoreElements();)
    { MapSheet mapSheet=(MapSheet)e.nextElement();
      mapSheet.writeRecord(rs,recordId); recordId++;
    }
  }

  private void loadAll() throws IOException,RecordStoreException
  { RecordStore rs = null;
    try
    { rs=RecordStore.openRecordStore(RECORDSTORE_NAME,true);
      if(rs.getNumRecords()<1) throw new IOException("no records");
      int n=readFirstRecord(rs);
      for(int i=0;i<n;i++)
      { AccountRecord rec=new AccountRecord(rs,i+2);
//      rec.readRecord(rs);
        accounts.addElement(rec);
      }
      for(int j=0;j<nMapSheets;j++) MapSheet.readRecord(rs,n+j+2);
      MapSheet.setSelectedMapSheet(selectedMapSheet);

    } finally { rs.closeRecordStore(); }
  }

  public String toString()
  { if(DEBUG) return("AccountRecordStore[accounts="+accounts+']');
    else return(super.toString());
  }

}
